﻿//#define DEBUG_MESSAGES
#define DB_MYSQL
#define DB_ACCESS

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net.Mail;

using DAO;
using DAO.DB;
using Code;
using Code.Data;

public partial class Completed : System.Web.UI.Page
{
    #region Fields

    /// <summary>
    /// The number of right questions the studend has achieved.
    /// </summary>
    protected int rightQuestions = -1;

    /// <summary>
    /// The number of questiosn the student has missed.
    /// </summary>
    protected int miss = -1;

    /// <summary>
    /// The points the student achieved.
    /// </summary>
    protected double pontuation = 0;

    /// <summary>
    /// The user solution string.
    /// </summary>
    protected string userSolution = "";

    /// <summary>
    /// The user solution string.
    /// </summary>
    protected string testSolution = "";

    /// <summary>
    /// To show the solution.
    /// </summary>
    protected bool showSolution = false;

    /// <summary>
    /// To show the pontuation.
    /// </summary>
    protected bool showPontuation = false;

    #endregion

    /// <summary>
    /// When the page loads.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The args.</param>
    protected void Page_Load(object sender, EventArgs e)
    {
        if (this.IsPostBack == false)
        {
            try
            {
                this.userSolution = this.Request.QueryString["s"];
                string id_test = this.Request.QueryString["g"];
                string id_student = this.Request.QueryString["k"];
                string modeS = this.Request.QueryString["i"];
                string cpf = this.Request.QueryString["v"];
                string questions_ids = "-1";

                if (string.IsNullOrEmpty(cpf) == true || cpf == "0")
                {
                    cpf = "00000000000";
                }

                int mode = -1;
                int.TryParse(modeS, out mode);

                if (string.IsNullOrEmpty(id_test) == true)
                {
                    this.Response.Write("Parametros invalidos.");
                    return;
                }

                DAO.DAO.Instance.Setup(DatabaseTypes.MySql, DataHelper.Instance.MySqlConnectionString);
                DAO.DAO.Instance.Connector.Open();

                // Getting the questions ids
                var reader = DAO.DAO.Instance.Connector.QueryWithReader("SELECT * FROM tb_TestStatus WHERE Excluido <> 1 AND id_test=" + id_test + " AND Id_Usuario=" + id_student);
                reader.Read();
                questions_ids = (string)reader["Questoes_Sorteadas"];
                reader.Close();
                DAO.DAO.Instance.Connector.Close();

                // Getting the questions
                string questions = DataHelper.Instance.GetQuestions(DAO.DAO.Instance.Connector, int.Parse(id_test), int.Parse(id_student), questions_ids);
                //Response.Write(questions);
                if (    string.IsNullOrEmpty(questions) == true
                     || string.IsNullOrEmpty(this.userSolution) == true
                     || string.IsNullOrEmpty(id_student) == true
                   )
                {
                    this.Response.Write("Parametros invalidos.");
                    return;
                }                

                // To calculate the pontuation
                this.CalculatePontuation(DAO.DAO.Instance.Connector, questions, int.Parse(id_test), int.Parse(id_student));

                string nomeCurso = "";
                int idCurso = -1;

                // Avoiding the overwrite of the finish date
                if (mode != 1)
                {
                    try
                    {
                        DAO.DAO.Instance.Connector.Open();
                        reader = DAO.DAO.Instance.Connector.QueryWithReader("select finishDate, done from tb_TestStatus WHERE Excluido <> 1 AND id_test=" + id_test + " AND Id_Usuario=" + id_student + " AND cpf=" + cpf);                        
                        reader.Read();

                        if ((int)reader["done"] == 1)
                        {
                            return;
                        }

                        if (reader["finishDate"] != null && (reader["finishDate"] is System.DBNull) == false)
                        {
                            if (string.IsNullOrEmpty((string)reader["finishDate"]) == false)
                            {
                                //return;
                            }
                        }

                        reader.Close();
                        DAO.DAO.Instance.Connector.Close();                        

                        // Saving the user data for the test
                        DAO.DAO.Instance.Connector.Open();
                        string pontuationBuffer = this.pontuation.ToString().Replace(',', '.');
                        DAO.DAO.Instance.Connector.Execute("update tb_TestStatus SET done=" + "1" + ", pts=" + pontuationBuffer + ", userSolution='" + this.userSolution + "', finishDate='" + DateTime.Now + "' WHERE Excluido <> 1 AND id_test=" + id_test + " AND Id_Usuario=" + id_student + " AND cpf=" + cpf);
                        DAO.DAO.Instance.Connector.Close();
                    }
                    catch (Exception errorTestStatus)
                    {
                        this.Response.Write("Erro ao cadastrar o stado do teste: " + errorTestStatus.Message + "\n" + errorTestStatus.StackTrace + "\n" + errorTestStatus.TargetSite);
                    }
                }

                string testName = "";
                if (mode != 1)
                {
                    // Checking if the test solution will be shown or not
                    DAO.DAO.Instance.Connector.Open();
                    reader = DAO.DAO.Instance.Connector.QueryWithReader("SELECT showSolution, showPontuation, tb_TestDef.testName, tb_Cursos.Nome_Curso, tb_TestDef.Id_Curso FROM tb_TestDef INNER JOIN tb_Cursos ON (tb_TestDef.Id_Curso = tb_Cursos.Id_Curso) WHERE id_testDef=" + id_test);
                    reader.Read();

                    if ((int)reader["showSolution"] == 1)
                    {
                        this.showSolution = true;
                    }

                    if ((int)reader["showPontuation"] == 1)
                    {
                        this.showPontuation = true;
                    }

                    nomeCurso = (string)reader["Nome_Curso"];
                    idCurso = (int)reader["Id_Curso"];
                    testName = (string)reader["testName"];

                    DAO.DAO.Instance.Connector.Close();
                    reader.Close();                       
                }
                else
                {
                    this.showSolution = true;
                    this.showPontuation = true;
                }

                // Getting the student data
                string emailUsuario = null;
                string nomeAluno = null;
                
                DAO.DAO.Instance.Connector.Open();
                var readerData = DAO.DAO.Instance.Connector.QueryWithReader("select Nome, NomedaEmpresa, Email FROM tb_Usuarios WHERE Id_Usuario=" + id_student);                
                readerData.Read();

                emailUsuario = (string)readerData["Email"];
                nomeAluno = (string)readerData["Nome"];
                if (string.IsNullOrEmpty(nomeAluno) == true)
                {
                    emailUsuario = (string)readerData["NomedaEmpresa"];
                }
                readerData.Close();
                DAO.DAO.Instance.Connector.Close();

                // To send the email to confirm that the user did the test
                this.SendTestCompletionEmail(emailUsuario, nomeAluno, cpf, int.Parse(id_student), testName, nomeCurso);

                // To check if the user did all tests, then send the confirmation email
                this.CheckCourseConclusion(idCurso, cpf, emailUsuario, int.Parse(id_student), nomeAluno, nomeCurso);
            }
            catch (Exception error)
            {
                this.Response.Write("1#Ocorreu um erro: " + error.Message + "\n" + error.StackTrace + "\n" + error.TargetSite);
            }
        }
    }

    /// <summary>
    /// To check if the user has concluded the course (did all tests).
    /// </summary>
    private void CheckCourseConclusion(int idCurso, string cpf, string emailUsuario, int id_student, string nomeAluno, string nomeCurso)
    {
        try
        {
            // Checando se todas as provas foram concluidas e enviando o email de conclusão do curso
            // Ids das provas do curso

            // id_test
            DAO.DAO.Instance.Connector.Open();
            var reader = DAO.DAO.Instance.Connector.QueryWithReader("SELECT id_TestDef, approvalPercentage FROM tb_TestDef WHERE Excluido = 0 AND Id_Curso =" + idCurso);            

            // Procurando todas as provas do curso
            List<double> medias = new List<double>();
            List<TestInformation> infos = new List<TestInformation>();

            int testCount = 0;
            while (reader.Read())
            {
                ++testCount;
                int idTestDef = -1;

                idTestDef = (int)reader["id_TestDef"];
                //idTestDef = (int)reader["approvalPercentage"];

                DAO.DAO.Instance.SecondConnector.Open();
                var reader2 = DAO.DAO.Instance.SecondConnector.QueryWithReader("SELECT tb_TestStatus.pts, tb_TestStatus.startDate, tb_TestStatus.finishDate, tb_TestDef.approvalPercentage, tb_TestDef.testName, tb_TestDef.Sortear_Questoes FROM tb_TestStatus INNER JOIN tb_TestDef ON (tb_TestStatus.id_test = tb_TestDef.id_TestDef) WHERE tb_TestStatus.Excluido <> 1 AND Done=1 AND id_test=" + idTestDef + " AND cpf=" + cpf + " AND Id_Usuario=" + id_student);
                if (reader2.Read() == true)
                {
                    // Calculando quanto vale a prova
                    double soma = -1;
                    double porcentagem = -1;
                    double porcentagemDoAluno = 0;
                    double pts = -1;

                    // TODO: Arrumar o -1 ali
                    DataHelper.Instance.GetQuestionsWithoutSolution(DAO.DAO.Instance.Connector, idTestDef, (int)reader2["Sortear_Questoes"], out soma, out porcentagem, false, id_student);

                    pts = (double)reader2["pts"];

                    porcentagemDoAluno = (pts * 100) / soma;
                    TestInformation testInfo = new TestInformation();
                    testInfo.Aproveitamento = porcentagemDoAluno;
                    testInfo.Nota = pts;
                    testInfo.TotalPontos = soma;
                    testInfo.Nome = (string)reader2["testName"];
                    testInfo.Inicio = (string)reader2["startDate"];
                    testInfo.Fim = (string)reader2["finishDate"];
                    testInfo.AproveitamentoParaAprovacao = (int)reader2["approvalPercentage"];

                    infos.Add(testInfo);
                    medias.Add(porcentagemDoAluno);

                    DAO.DAO.Instance.SecondConnector.Close();
                }
                else
                {
                    DAO.DAO.Instance.SecondConnector.Close();
                    // Nao fez a prova, entao nao da para enviar a media final
                    throw new Exception("erro1");
                }
            }

            // Vendo se o usuario terminou todas as provas
            if (medias.Count == testCount)
            {
                double notaTotal = 0;
                double valorTotal = 0;
                double final = 0;
                foreach (TestInformation tp in infos)
                {
                    notaTotal += tp.Nota;
                    valorTotal += tp.TotalPontos;
                }
                final = (notaTotal * 100) / valorTotal;
                this.SendCourseCompletionEmail(final, nomeAluno as string, emailUsuario as string, nomeCurso, cpf, infos);

                // Escrevendo no banco a data de termino do curso
                DAO.DAO.Instance.Connector.Open();
                DAO.DAO.Instance.Connector.Execute("UPDATE tb_Matriculas SET Data_Conclusao='" + String.Format("{0:dd/MM/yyyy HH:mm:ss}", DateTime.Now) + "', PorcentagemNotas='" + final + "' WHERE Pago = 1 AND Excluido <> 1 AND Id_Usuario=" + id_student + " AND Id_Curso=" + idCurso);
                DAO.DAO.Instance.Connector.Close();
            }
        }
        catch (Exception email2Error)
        {
            if (email2Error.Message != "erro1")
            {
                this.Response.Write("Erro no envio do email final: " + email2Error.Message + "<br />" + email2Error.StackTrace + "<br />" + email2Error.TargetSite + "<br />Nome: " + nomeAluno + " Email: " + emailUsuario);
            }
        }
    }

    /// <summary>
    /// Calculate the pontuation.
    /// </summary>
    /// <param name="questions"></param>
    /// <returns></returns>
    public void CalculatePontuation(BaseConnector connector, string questions, int id_test, int id_student)
    {       
        // Getting the questions and the solutions
        string[] questionData = questions.Split('Ą');
        List<int> rightSolution = new List<int>();
        List<double> questionPontuation = new List<double>();
        foreach (string question in questionData)
        {
            string[] questionParams = question.Split('Ę');
            rightSolution.Add(DataHelper.Instance.Decrypt(questionParams[5]));
            questionPontuation.Add(double.Parse(questionParams[6]));
        }

        // Calculating the pontuation
        int count = 0;
        int right = 0;
        this.testSolution = "";
        foreach (char number in this.userSolution)
        {
            this.testSolution += rightSolution[count];
            if (rightSolution[count] == int.Parse("" + number))
            {
                right++;
                this.pontuation += questionPontuation[count];
            }

            count++;
        }

        this.rightQuestions = right;
        this.miss = rightSolution.Count - right;
    }

    /// <summary>
    ///  Sends the email to confirm that the user did the test
    /// </summary>
    private void SendTestCompletionEmail(string emailUsuario, string nomeAluno, string cpf, int id_student, string testName, string nomeCurso)
    {
        try
        {
            // Mensagem do email
            string bodyMessage = "Olá.";
            bodyMessage += "<br />";
            bodyMessage += "<br />";
            if (nomeAluno is string && string.IsNullOrEmpty(nomeAluno as string) == false)
            {
                bodyMessage += "Parabéns <strong>" + (nomeAluno as string) + "</strong> (" + emailUsuario + ") ! ";
            }
            else
            {
                bodyMessage += "Parabéns! ";
            }

            bodyMessage += "<br />";
            bodyMessage += "<br />";

            string percentage = this.CalculatePorcentage(this.rightQuestions, this.rightQuestions + this.miss);
            if (cpf == "00000000000")
            {
                bodyMessage += "Você concluiu a prova <strong>'" + testName + "'</strong> do curso <strong>'" + nomeCurso + "'</strong> com a nota de <strong>" + this.pontuation + " pontos</strong> e aproveitamento de <strong>" + percentage + "%</strong>.";
            }
            else
            {
                bodyMessage += "Você concluiu a prova <strong>'" + testName + "'</strong> do curso <strong>'" + nomeCurso + "'</strong> utilizando o cpf (" + cpf + ") com a nota de <strong>" + this.pontuation + " pontos</strong> e aproveitamento de <strong>" + percentage + "%</strong>.";
            }

            bodyMessage += "<br />";
            bodyMessage += "<br />";
            bodyMessage += "Não deixe de visitar o portal (www.elfutec.com.br) e conhecer novos cursos!";
            bodyMessage += "<br />";
            bodyMessage += "<br />";
            bodyMessage += "Nos dias atuais, formar-se e especializar-se é algo decisivo para a carreira de qualquer um. É o melhor caminho para crescer profissionalmente ou mesmo mudar de profissão. A capacitação e a busca constante do conhecimento são os diferenciais dos profissionais.";
            bodyMessage += "<br />";
            bodyMessage += "<br />";
            bodyMessage += "Atenciosamente,";
            bodyMessage += "<br />";
            bodyMessage += "<br />";
            bodyMessage += "Equipe ELFUTEC";
            bodyMessage += "<br />";
            bodyMessage += "www.elfutec.com.br";

            // Enviando o email        
            //Cria novo objeto MailMessage  
            MailMessage mailMessage = new MailMessage();
            //Define o remetente    
            mailMessage.From = new MailAddress("coordenacao@elfutec.com.br");
            //Define primeiro destinatário  
            if (emailUsuario is string && string.IsNullOrEmpty(emailUsuario as string) == false)
            {
                mailMessage.To.Add(emailUsuario as string);
            }

            mailMessage.CC.Add("coordenacao@elfutec.com.br");
            mailMessage.CC.Add("atendimento@elfutec.com.br");
            //Define assunto do e-mail  
            mailMessage.Subject = "Prova Concluída";
            //Seta propriedade para enviar email em html como true(verdadeiro)  
            mailMessage.IsBodyHtml = true;
            //Seta o corpo do e-mail com a estrutura HTML gravada na stringbuilder sbBody  
            mailMessage.Body = bodyMessage;

            //Cria novo SmtpCliente e seta o endereço  
            SmtpClient smtpClient = new SmtpClient("smtp-web.uni5.net");
            // Envia a mensagem     
            smtpClient.Send(mailMessage);

        }
        catch (Exception emailError)
        {
            this.Response.Write("Erro no envio do email: " + emailError.Message);
        }
    }

    /// <summary>
    /// To send the email when he user have complete the course.
    /// </summary>
    /// <param name="mediaFinal"></param>
    /// <param name="nomeAluno"></param>
    /// <param name="emailUsuario"></param>
    /// <param name="nomeCurso"></param>
    /// <param name="cpf"></param>
    public void SendCourseCompletionEmail(double mediaFinal, string nomeAluno, string emailUsuario, string nomeCurso, string cpf, List<TestInformation> testsInfos)
    {
        // Mensagem do email
        string bodyMessage = "";
        if (string.IsNullOrEmpty(nomeAluno as string) == false)
        {
            bodyMessage += "Olá <strong>" + nomeAluno + "</strong> (" + emailUsuario + ") .";
        }
        else
        {
            bodyMessage += "Olá.";
        }

        bodyMessage += "<br />";
        bodyMessage += "<br />";

        if (cpf == "00000000000")
        {
            bodyMessage += "Você concluiu todas as provas do curso <strong>'" + nomeCurso + "'</strong> com a média final de <strong>" + mediaFinal.ToString("F2") + "%</strong>.";
        }
        else
        {
            bodyMessage += "Você concluiu todas as provas do curso <strong>'" + nomeCurso + "'</strong> utlizando o cpf (" + cpf + ") com a média final de <strong>" + mediaFinal.ToString("F2") + "%</strong>.";
        }

        bodyMessage += "<br />";

        if (mediaFinal >= 70)
        {
            //bodyMessage += "Seu certificado de conclusão do <strong>" + nomeCurso + "</strong> será gerado e enviado dentro de alguns dias.";
        }
        else
        {
            bodyMessage += "A média necessária para a conclusão do curso é de <strong>70%</strong>.";
            bodyMessage += "<br />";
            bodyMessage += "<br />";
            bodyMessage += "Marque uma reavaliação.";
            bodyMessage += "<br />";
            bodyMessage += "Entre em contato com um de nossos consultores através do 0800 033 9904 para mais informações.";
            bodyMessage += "<br />";
        }

        if (testsInfos != null && testsInfos.Count > 0)
        {
            bodyMessage += "<br />";
            bodyMessage += "<strong>Histórico de Avaliações</strong>";
            bodyMessage += "<br />";
            foreach (TestInformation test in testsInfos)
            {
                bodyMessage += "<strong>Prova</strong>: " + test.Nome;
                bodyMessage += "<br />";
                bodyMessage += "<strong>Aproveitamento para aprovação</strong>: " + test.AproveitamentoParaAprovacao + "%";
                bodyMessage += "<br />";
                bodyMessage += "<strong>Nota alcançada</strong>: " + test.Nota + " pontos";
                bodyMessage += "<br />";
                bodyMessage += "<strong>Aproveitamento alcançado</strong>: " + test.Aproveitamento + "%";
                bodyMessage += "<br />";
                bodyMessage += "<strong>Data início</strong>: " + test.Inicio;
                bodyMessage += "<br />";
                bodyMessage += "<strong>Data término</strong>: " + test.Fim;
                bodyMessage += "<br />";
                bodyMessage += "<br />";
            }
        }
        else
        {
            bodyMessage += "<br />";
            bodyMessage += "<br />";
        }

        bodyMessage += "Não deixe de visitar o portal (www.elfutec.com.br) e conhecer novos cursos!";
        bodyMessage += "<br />";
        bodyMessage += "<br />";
        bodyMessage += "Nos dias atuais, formar-se e especializar-se é algo decisivo para a carreira de qualquer um. É o melhor caminho para crescer profissionalmente ou mesmo mudar de profissão. A capacitação e a busca constante do conhecimento são os diferenciais dos profissionais.";
        bodyMessage += "<br />";
        bodyMessage += "<br />";
        bodyMessage += "Atenciosamente,";
        bodyMessage += "<br />";
        bodyMessage += "<br />";
        bodyMessage += "Equipe ELFUTEC";
        bodyMessage += "<br />";
        bodyMessage += "www.elfutec.com.br";

        // Enviando o email        
        MailMessage mailMessage = new MailMessage();
        //Define o remetente    
        mailMessage.From = new MailAddress("coordenacao@elfutec.com.br");
        //Define primeiro destinatário  
        if (emailUsuario is string && string.IsNullOrEmpty(emailUsuario as string) == false)
        {
            mailMessage.To.Add(emailUsuario as string);
        }

        mailMessage.CC.Add("coordenacao@elfutec.com.br");
        mailMessage.CC.Add("atendimento@elfutec.com.br");
        //Define assunto do e-mail  
        mailMessage.Subject = "Curso Concluído";
        //Seta propriedade para enviar email em html como true(verdadeiro)  
        mailMessage.IsBodyHtml = true;
        //Seta o corpo do e-mail com a estrutura HTML gravada na stringbuilder sbBody  
        mailMessage.Body = bodyMessage;

        //Cria novo SmtpCliente e seta o endereço  
        SmtpClient smtpClient = new SmtpClient("smtp-web.uni5.net");
        smtpClient.Send(mailMessage);
    }

    /// <summary>
    /// To calculate a percentage.
    /// </summary>
    /// <param name="current"></param>
    /// <param name="total"></param>
    /// <returns></returns>
    public string CalculatePorcentage(float current, float total)
    {
        float final = (current * 100) / total;
        return final.ToString("F2");
    }

    public class TestInformation
    {
        #region Properties

        public string Nome
        {
            get;
            set;
        }

        public double TotalPontos
        {
            get;
            set;
        }

        public double Nota
        {
            get;
            set;
        }

        public double Aproveitamento
        {
            get;
            set;
        }

        public double AproveitamentoParaAprovacao
        {
            get;
            set;
        }

        public string Inicio
        {
            get;
            set;
        }

        public string Fim
        {
            get;
            set;
        }
        #endregion
    }
}